home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / n8250.c < prev    next >
C/C++ Source or Header  |  1992-05-28  |  7KB  |  379 lines

  1. /* @(#) $Header: n8250.c,v 1.17 92/05/28 13:50:25 deyke Exp $ */
  2.  
  3. #include <sys/types.h>
  4.  
  5. #include <fcntl.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <termio.h>
  9. #include <unistd.h>
  10.  
  11. #if defined(ISC) || defined(SCO)
  12. #include <sys/tty.h>
  13. #include <sys/stream.h>
  14. #include <sys/ptem.h>
  15. #ifdef ISC
  16. #include <sys/pty.h>
  17. #endif
  18. #ifdef SCO
  19. #include <sys/vty.h>
  20. #endif
  21. #define FIOSNBIO        FIONBIO
  22. #endif
  23.  
  24. #include "global.h"
  25. #include "mbuf.h"
  26. #include "proc.h"
  27. #include "iface.h"
  28. #include "n8250.h"
  29. #include "asy.h"
  30. #include "devparam.h"
  31. #include "hpux.h"
  32. #include "timer.h"
  33.  
  34. static int find_speed __ARGS((long speed));
  35. static void pasy __ARGS((struct asy *asyp));
  36. static void asy_tx __ARGS((struct asy *asyp));
  37.  
  38. struct asy Asy[ASY_MAX];
  39.  
  40. /*---------------------------------------------------------------------------*/
  41.  
  42. static struct {
  43.     long speed;
  44.     int flags;
  45. } speed_table[] = {
  46. #ifdef B50
  47.     50, B50,
  48. #endif
  49. #ifdef B75
  50.     75, B75,
  51. #endif
  52. #ifdef B110
  53.     110, B110,
  54. #endif
  55. #ifdef B134
  56.     134, B134,
  57. #endif
  58. #ifdef B150
  59.     150, B150,
  60. #endif
  61. #ifdef B200
  62.     200, B200,
  63. #endif
  64. #ifdef B300
  65.     300, B300,
  66. #endif
  67. #ifdef B600
  68.     600, B600,
  69. #endif
  70. #ifdef B900
  71.     900, B900,
  72. #endif
  73. #ifdef B1200
  74.     1200, B1200,
  75. #endif
  76. #ifdef B1800
  77.     1800, B1800,
  78. #endif
  79. #ifdef B2400
  80.     2400, B2400,
  81. #endif
  82. #ifdef B3600
  83.     3600, B3600,
  84. #endif
  85. #ifdef B4800
  86.     4800, B4800,
  87. #endif
  88. #ifdef B7200
  89.     7200, B7200,
  90. #endif
  91. #ifdef B9600
  92.     9600, B9600,
  93. #endif
  94. #ifdef B19200
  95.     19200, B19200,
  96. #endif
  97. #ifdef B38400
  98.     38400, B38400,
  99. #endif
  100. #ifdef B57600
  101.     57600, B57600,
  102. #endif
  103. #ifdef B115200
  104.     115200, B115200,
  105. #endif
  106. #ifdef B230400
  107.     230400, B230400,
  108. #endif
  109. #ifdef B460800
  110.     460800, B460800,
  111. #endif
  112.     -1, 0
  113. };
  114.  
  115. /*---------------------------------------------------------------------------*/
  116.  
  117. static int
  118. find_speed(speed)
  119. long speed;
  120. {
  121.     int i;
  122.  
  123.     i = 0;
  124.     while (speed_table[i].speed < speed && speed_table[i+1].speed > 0)
  125.         i++;
  126.     return i;
  127. }
  128.  
  129. /*---------------------------------------------------------------------------*/
  130.  
  131. /* Initialize asynch port "dev" */
  132. int
  133. asy_init(dev,ifp,arg1,arg2,bufsize,trigchar,monitor,speed)
  134. int dev;
  135. struct iface *ifp;
  136. char *arg1,*arg2;       /* Attach args for address and vector */
  137. int16 bufsize;
  138. int trigchar;
  139. char monitor;
  140. long speed;
  141. {
  142.     register struct asy *ap;
  143.     char filename[80];
  144.     int sp;
  145.     long arg;
  146.     struct termio termio;
  147.  
  148.     ap = &Asy[dev];
  149.     strcpy(filename, "/dev/");
  150.     strcat(filename, ifp->name);
  151.     if ((ap->fd = open(filename, O_RDWR, 0666)) < 0) goto Fail;
  152.     ap->iface = ifp;
  153.     sp = find_speed(speed);
  154.     ap->speed = speed_table[sp].speed;
  155.     termio.c_iflag = IGNBRK | IGNPAR;
  156.     termio.c_oflag = 0;
  157.     termio.c_cflag = speed_table[sp].flags | CS8 | CREAD | CLOCAL;
  158.     termio.c_lflag = 0;
  159.     termio.c_line = 0;
  160.     termio.c_cc[VMIN] = 0;
  161.     termio.c_cc[VTIME] = 0;
  162.     if (ioctl(ap->fd, TCSETA, &termio) == -1) goto Fail;
  163.     if (ioctl(ap->fd, TCFLSH, 2) == -1) goto Fail;
  164.     arg = 1;
  165.     ioctl(ap->fd, FIOSNBIO, &arg);  /*** will fail on pty master side ***/
  166.     on_read(ap->fd, (void (*)()) ifp->rxproc, ifp);
  167.     return 0;
  168.  
  169. Fail:
  170.     if (ap->fd >= 0) close(ap->fd);
  171.     ap->iface = NULLIF;
  172.     return -1;
  173. }
  174.  
  175. /*---------------------------------------------------------------------------*/
  176.  
  177. int
  178. asy_stop(ifp)
  179. struct iface *ifp;
  180. {
  181.     register struct asy *ap;
  182.  
  183.     ap = &Asy[ifp->dev];
  184.  
  185.     if(ap->iface == NULLIF)
  186.         return -1;      /* Not allocated */
  187.     ap->iface = NULLIF;
  188.  
  189.     off_read(ap->fd);
  190.     off_write(ap->fd);
  191.     free_q(&ap->sndq);
  192.     close(ap->fd);
  193.  
  194.     return 0;
  195. }
  196.  
  197. /*---------------------------------------------------------------------------*/
  198.  
  199. /* Set asynch line speed */
  200. int
  201. asy_speed(dev,bps)
  202. int dev;
  203. long bps;
  204. {
  205.  
  206.     struct asy *asyp;
  207.     int sp;
  208.     struct termio termio;
  209.  
  210.     if(bps <= 0 || dev >= ASY_MAX)
  211.         return -1;
  212.     asyp = &Asy[dev];
  213.     if(asyp->iface == NULLIF)
  214.         return -1;
  215.  
  216.     if(bps == 0)
  217.         return -1;
  218.     sp = find_speed(bps);
  219.     if (ioctl(asyp->fd, TCGETA, &termio))
  220.         return -1;
  221.     termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_table[sp].flags;
  222.     if (ioctl(asyp->fd, TCSETA, &termio))
  223.         return -1;
  224.     asyp->speed = speed_table[sp].speed;
  225.     return 0;
  226. }
  227.  
  228. /*---------------------------------------------------------------------------*/
  229.  
  230. /* Asynchronous line I/O control */
  231. int32
  232. asy_ioctl(ifp,cmd,set,val)
  233. struct iface *ifp;
  234. int cmd;
  235. int set;
  236. int32 val;
  237. {
  238.     struct asy *ap = &Asy[ifp->dev];
  239.  
  240.     switch(cmd){
  241.     case PARAM_SPEED:
  242.         if(set)
  243.             asy_speed(ifp->dev,val);
  244.         return ap->speed;
  245.     }
  246.     return -1;
  247. }
  248.  
  249. /*---------------------------------------------------------------------------*/
  250.  
  251. int
  252. get_asy(dev, buf, cnt)
  253. int dev;
  254. char *buf;
  255. int cnt;
  256. {
  257.     struct asy *ap;
  258.  
  259.     ap = &Asy[dev];
  260.     if(ap->iface == NULLIF)
  261.         return 0;
  262.     cnt = read(ap->fd,buf,cnt);
  263.     ap->rxints++;
  264.     if (cnt <= 0)
  265.         return 0;
  266.     ap->rxchar += cnt;
  267.     if (ap->rxhiwat < cnt)
  268.         ap->rxhiwat = cnt;
  269.     return cnt;
  270. }
  271.  
  272. /*---------------------------------------------------------------------------*/
  273.  
  274. int
  275. doasystat(argc,argv,p)
  276. int argc;
  277. char *argv[];
  278. void *p;
  279. {
  280.     register struct asy *asyp;
  281.     struct iface *ifp;
  282.     int i;
  283.  
  284.     if(argc < 2){
  285.         for(asyp = Asy;asyp < &Asy[ASY_MAX];asyp++){
  286.             if(asyp->iface != NULLIF)
  287.                 pasy(asyp);
  288.         }
  289.         return 0;
  290.     }
  291.     for(i=1;i<argc;i++){
  292.         if((ifp = if_lookup(argv[i])) == NULLIF){
  293.             printf("Interface %s unknown\n",argv[i]);
  294.             continue;
  295.         }
  296.         for(asyp = Asy;asyp < &Asy[ASY_MAX];asyp++){
  297.             if(asyp->iface == ifp){
  298.                 pasy(asyp);
  299.                 break;
  300.             }
  301.         }
  302.         if(asyp == &Asy[ASY_MAX])
  303.             printf("Interface %s not asy\n",argv[i]);
  304.     }
  305.  
  306.     return 0;
  307. }
  308.  
  309. /*---------------------------------------------------------------------------*/
  310.  
  311. static void
  312. pasy(asyp)
  313. struct asy *asyp;
  314. {
  315.  
  316.     printf("%s:",asyp->iface->name);
  317.  
  318.     printf(" %lu bps\n",asyp->speed);
  319.  
  320.     printf(" RX: int %lu chars %lu hw hi %lu\n",
  321.      asyp->rxints,asyp->rxchar,asyp->rxhiwat);
  322.     asyp->rxhiwat = 0;
  323.  
  324.     printf(" TX: int %lu chars %lu%s\n",
  325.      asyp->txints,asyp->txchar,
  326.      asyp->sndq ? " BUSY" : "");
  327. }
  328.  
  329. /*---------------------------------------------------------------------------*/
  330.  
  331. /* Serial transmit process, common to all protocols */
  332. static void
  333. asy_tx(asyp)
  334. struct asy *asyp;
  335. {
  336.     int n;
  337.  
  338.     if (asyp->sndq != NULLBUF) {
  339.         n = write(asyp->fd, asyp->sndq->data, asyp->sndq->cnt);
  340.         asyp->txints++;
  341.         if (n > 0) {
  342.             asyp->txchar += n;
  343.             asyp->sndq->data += n;
  344.             asyp->sndq->cnt -= n;
  345.             if(asyp->sndq->cnt == 0){
  346.                 asyp->sndq = free_mbuf(asyp->sndq);
  347.                 if (asyp->sndq == NULLBUF)
  348.                     off_write(asyp->fd);
  349.             }
  350.         }
  351.     }
  352. }
  353.  
  354. /*---------------------------------------------------------------------------*/
  355.  
  356. /* Send a message on the specified serial line */
  357. int
  358. asy_send(dev,bp)
  359. int dev;
  360. struct mbuf *bp;
  361. {
  362.     struct asy *asyp;
  363.  
  364.     if(dev < 0 || dev >= ASY_MAX){
  365.         free_p(bp);
  366.         return -1;
  367.     }
  368.     asyp = &Asy[dev];
  369.  
  370.     if(asyp->iface == NULLIF)
  371.         free_p(bp);
  372.     else {
  373.         append(&asyp->sndq, bp);
  374.         on_write(asyp->fd, (void (*)()) asy_tx, asyp);
  375.     }
  376.     return 0;
  377. }
  378.  
  379.